package io.argin.controller;


import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.conf.HystrixPropertiesManager;
import io.argin.entity.Dept;
import io.argin.entity.Emp;
import io.argin.feign.EmpFeign;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author argin
 * @since 2020-12-25
 */
@Controller
public class EmpControllerPlus {

    @Resource
    private EmpFeign feign;

    @GetMapping("/")
    public String emp() {
        return "redirect:/list";
    }

    @GetMapping("/insert")
    public ModelAndView insert(ModelAndView mv) {
        List<Dept> list = feign.listDepts();
        mv.addObject("ds", list);
        mv.setViewName("insert");
        return mv;
    }

    @PostMapping("/insert")
    public String insertEmp(Emp emp) {
        System.out.println("consumer:insert");
        System.out.println("emp = " + emp);
        feign.insertEmp(emp);
        return "redirect:/list";
    }

    @GetMapping("/map/insert")
    public ModelAndView insertMap(ModelAndView mv) {
        List<Dept> list = feign.listDepts();
        mv.addObject("ds", list);
        mv.setViewName("insertMap");
        return mv;
    }

    @PostMapping("/map/insert")
    public String insertEmpMap(@RequestBody Map<String, Object> map) {
        System.out.println("consumer:insert");
        System.out.println("map = " + map);
        feign.insertMap(map);
        return "redirect:/list";
    }

    @GetMapping("/delete/{id}")
    public String deleteEmp(@PathVariable Integer id) {
        feign.deleteEmp(id);
        return "redirect:/list";
    }

    @GetMapping("/update/{id}")
    public ModelAndView getEmpById(ModelAndView mv, @PathVariable Integer id) {
        mv.addObject("emp", feign.getEmp(id));
        mv.addObject("ds", feign.listDepts());
        mv.setViewName("update");
        return mv;
    }

    @PostMapping("/update")
    public String updateEmp(Emp emp) {
        System.out.println("consumer:update");
        System.out.println("emp = " + emp);
        feign.updateEmp(emp);
        return "redirect:/list";
    }

    public Emp fallback(){
        Emp emp = new Emp();
        emp.setId(6);
        emp.setName("任毅");
        return emp;
    }

    @HystrixCommand(fallbackMethod = "fallback",
            commandProperties = {
                    //错误百分比条件，达到熔断器最小请求数后错误率达到百分之多少后打开熔断器
                    @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE, value = "5"),
                    //断容器最小请求数，达到这个值过后才开始计算是否打开熔断器
                    @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD, value = "3"),
                    // 默认5秒; 熔断器打开后多少秒后 熔断状态变成半熔断状态(对该微服务进行一次请求尝试，不成功则状态改成熔断，成功则关闭熔断器
                    @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS, value = "5000")
            })
    @ResponseBody
    @GetMapping("/get")
    public Emp getEmpById(Integer id) {
        return feign.getEmpById(id);
    }

    @GetMapping("/list/{name}")
    public ModelAndView listEmpsByName(ModelAndView mv, @PathVariable String name) {
        mv.addObject("list", feign.listEmpsByName(name));
        mv.setViewName("list");
        return mv;
    }

    @GetMapping("/list")
    public ModelAndView listEmps(ModelAndView mv) {
        mv.addObject("list", feign.listEmps());
        mv.setViewName("list");
        return mv;
    }

}
